//
// Created by lenovo on 2024/6/30.
//

#ifndef TEYVATSURVIVAL_PHYSICS_COLLISION_COLLISION_H
#define TEYVATSURVIVAL_PHYSICS_COLLISION_COLLISION_H
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <cmath>
#include <iostream>
using Vector2f = sf::Vector2f;
namespace Phy::Collision{
    class iCollider{
    public :
        virtual bool intersect( iCollider& other) = 0;
    };

    class AABB ; class CircleCollider ; class PointCollider ;

    /**
     * @brief
     * 将不同的collider注册于此处
     * 通过继承实现其中的方法
     */
    class Collider : public iCollider{
    public:
        virtual bool intersectWithAABB( AABB& aabb)  {
            std::cout << "UnDefined Collide Detect Method" << std::endl ;
            return false ;
        };
        virtual bool intersectWithCircle( CircleCollider& circle) {
            std::cout << "UnDefined Collide Detect Method" << std::endl ;
            return false ;
        };;
        virtual bool intersectWithPoint(PointCollider& point) {
            std::cout << "UnDefined Collide Detect Method" << std::endl ;
            return false ;
        }; ;
        virtual void move(const sf::Vector2f& delta){
            std::cout << "UnDefined Collider Move Method" << std::endl ;
        }
    };

    class AABB : public Collider {
    public:
        Vector2f position;
        Vector2f scale;

        AABB() {}

        AABB(Vector2f position, Vector2f scale)
                : position(position), scale(scale) {}

        bool intersect(iCollider& other) override {
            return dynamic_cast<Collider&>(other).intersectWithAABB(*this);
        }

        void setPosition(Vector2f p) { position.x = p.x ; position.y = p.y;}
        void setScale(Vector2f s) {scale = s ;}
        void move (const Vector2f& delta) override{position += delta;}
        bool intersectWithAABB(AABB& aabb) override;
        bool intersectWithCircle(CircleCollider& circle) override;
        bool intersectWithPoint(PointCollider& point) override;
    };

    class CircleCollider : public Collider {
    public:
        Vector2f position;
        float radius;

        CircleCollider() = default ;

        CircleCollider(Vector2f position, float radius)
                : position(position), radius(radius) {}

        bool intersect(iCollider& other) override {
            return dynamic_cast<Collider&>(other).intersectWithCircle(*this);
        }

        float getRadius () const {return radius;}
        void setPosition(Vector2f p) {position = p ;}
        void setRadius (float r) {radius = r;}
        void move (const sf::Vector2f& delta) override{position += delta;}
        bool intersectWithAABB(AABB& aabb) override ;
        bool intersectWithCircle(CircleCollider& circle) override;
        bool intersectWithPoint(PointCollider& point) override;
    };

    class PointCollider : public Collider {
    public:
        Vector2f position;

        PointCollider(Vector2f position) : position(position) {}

        bool intersect(iCollider& other) override {
            return dynamic_cast<Collider&>(other).intersectWithPoint(*this);
        }
        void move (const Vector2f& delta) override{position += delta;}
        bool intersectWithAABB(AABB& aabb) override ;
        bool intersectWithCircle(CircleCollider& circle) override ;
        bool intersectWithPoint(PointCollider& point) override;
    };


    extern void drawCollider(sf::RenderWindow& window, Phy::Collision::AABB& aabb);
    extern void drawCollider(sf::RenderWindow& window, Phy::Collision::CircleCollider& circle);
    extern void drawCollider(sf::RenderWindow& window, Phy::Collision::PointCollider& point);
}


#endif //TEYVATSURVIVAL_PHYSICS_COLLISION_COLLISION_H
